'''
	内存管理
	1. 引用
	2. 垃圾回收机制
	3. 循环垃圾回收
	4. 内存池
'''

# 任何程序 或 软件在运行时, 都是临时存放在内存中的


# 1. 引用
# ----------------------------------------
# 	python内部使用引用计数, 来保持内存中对象的追踪

a = 10
# 分析:
# 	10 是对象
# 	a 是引用
# 	
# 	a引用了 对象10,  对象10 的引用计数为 1


b = 10
# 分析:
# 	10 是对象
# 	b 是引用
# 	
# 	b引用了 对象10, 对象10 的引用计数为 2  (有a, 还有b)



# 问题1:
# 	a 和 b 是否引用的 同一个对象10 ???
print( id(a) )
print( id(b) )


# 问题2:
#  	若 a突然引用了别的对象, 那么 b 和 对象10 会受到影响吗???
a = 20

print( a, b )
print( id(a) )
print( id(b) )


# 回顾:
# 	由此内存变化, 证明 Number 被认为是 不可变类型的原因





# 2. 垃圾回收机制
# ----------------------------------------

# 每定义一个变量, 都会在内存划分空间, 在内存里面的值都统称为 对象
# 那么内存由于有上限, 那么python 在使用完变量, 就会查看 引用计数
# 
# 如果 引用计数 = 0, python 会立马释放内存 ( 垃圾回收 )

# 小结:
# 	对象在以下情况引用计数 + 1
# 	1) 对象被创建:  a = 10
# 	2) 对象被其他对象赋值: b = a
# 	3) 被作为参数传递给函数: 函数名( a )
# 	4) 作为容器对象的一个元素: x = [ 10, a, 03, ...]
# 	
# 	
# 	对象在以下情况引用计数 - 1
# 	1) 对象被销毁时: del a
# 	2) 对象引用别的对象: a = 20
# 	3) 引用离开了它的作用域时:  例如: 函数名(a)  在使用函数时, 计数+1, 一旦函数结束时, 计数-1
# 	
# 强调: 变量并不是直接存储, 而是引用了一个内存地址
# 强调: 变量并不是直接存储, 而是引用了一个内存地址
# 强调: 变量并不是直接存储, 而是引用了一个内存地址

print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')


# 3. 循环垃圾回收
# ----------------------------------------
# 	当出现两个变量 互相引用, 但两个变量又没有别的引用, 也会被当做垃圾回收掉

# x = y
# y = x 


# 4. 内存池
# ----------------------------------------
# 	在python运行期间, 会大量执行 内存malloc(分配)  和  free(释放), 导致python运行效率降低
# 	
# 	为了能加加速高频率数字, 引用内存池机制, 用于管理 小块内存的分配和释放
# 	只有在超过 小块内存, 才会去 malloc
#  	
#  	小块内存:
#  		整数范围: -5 ~ 256
#  		
#  		只要在 范围之内, 都是事先分配好的内存, 不会变. 只有超过这个范围, 才会去找python重新分配内存.

a = -5
print(a, id(a))


a = 6
print(a, id(a))


a = 256
print(a, id(a))


a = 257
print(a, id(a))

